#pragma once

#include "Top10.h"
#include "GameStats.h"
#include "Connection.h"
#include "GameClient.h"
#include "BagManager.h"
#include "BoardManager.h"
#include "TileMessage.h"
#include "PipeListener.h"
#include "Dictionary.h"

#include <Windows.h>
#include <vector>

using namespace std;

class Server : public PipeListener
{
private:
	static Server *s_instance;
	Server(void);

private:
	Top10 mTop10;
	GameStats mStats;

	Connection* mInConnection;

	vector<GameClient*> mClients;
	
	HANDLE mClientsSem;
	HANDLE mStateSem;

	int mState;

	BagManager mBag;
	BoardManager mBoard;
	Dictionary mDictionary;

private:
	static DWORD WINAPI HandleLoginMessage(LPVOID param);
	bool PlayerIsAlreadyLogged(string _username);
	void AddGameClient(GameClient* _newClient);
	void LoadTop10();
	static DWORD WINAPI StartCountDown(LPVOID param);

public:
	static Server *Instance();
	~Server(void);
	virtual bool HandleReceivedData(BYTE* _data);
	virtual Connection* GetInConnection();
	void StartNewGame();
	void BroadcastTop10();
	void BroadcastGameStats();
	void BroadcastBoardLineLock(UINT _line);
	void BroadcastBagTileLock(UINT _linha, UINT _col);
	void BroadcastBagTileUnlock(UINT _linha, UINT _col);
	void BroadcastPlaceBoardLetter(TileMessage* _msg);
	void BroadcastPlaceBagLetter(UINT _linha, UINT _col, char _letter);
	void DistributePoints(UINT _line);
	void LockClients();
	void UnlockClients();
	void ResetGame();
	void CheckForGameOver();

public:
	int State() const;
	void State(int val);
	HANDLE ClientsSem() const { return mClientsSem; }
	vector<GameClient*>& Clients() { return mClients; }
	Top10& Top10() { return mTop10; }
	GameStats& Stats() { return mStats; }
	BagManager& Bag() { return mBag; }
	BoardManager& Board() { return mBoard; }
	Dictionary& Dictionary() { return mDictionary; }
};

